﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyTurret2 : EnemyBaseFixed
{
    [System.Serializable]
    public struct LookAtSprite
    {
        public LookAtDirection12 lookAtDirection;
        public Sprite sprite;
    }
    [Header("基础配置")]
    public LookAtSprite[] lookAtSpriteConfig;
    public float rotateIntervalTime = 1f;

    private Vector2 targetDirection;

    public SpriteSequence prepareSpriteSequence;
    public SeqAction rotateAction = new() { intervalTime = 1f };

    private Collider2D collider2d;
    private SpriteRenderer sr;
    private Transform flashBack;

    private void Awake()
    {
        base.Init();
        collider2d = GetComponent<Collider2D>();
        sr = GetComponent<SpriteRenderer>();
        flashBack = transform.Find("FlashBack");
        lookAt = Vector2.left;
        needTurnAround = false;
    }
    void Start()
    {
        Run();
    }

    private void FixedUpdate()
    {
        base.CommonFixedUpdate();
    }

    protected void UpdateStateNone(bool stateChanged, EnumState inState, out EnumState outState)
    {
        outState = inState;
        if (AllInViewPort())
        {
            outState = EnumState.Prepare;
        }
        collider2d.enabled = false;
        sr.sprite = null;
        Vector3 scale = flashBack.localScale;
        scale.y = 0;
        flashBack.localScale = scale;
    }
    protected void UpdateStatePrepare(bool stateChanged, EnumState inState, out EnumState outState)
    {
        outState = inState;

        if (stateChanged)
        {
            prepareSpriteSequence.Restart();
        }

        collider2d.enabled = false;
        prepareSpriteSequence.Update(gameObject, transform.localScale);
        int progressIndex = prepareSpriteSequence.GetCurrentIndex();
        Vector3 flashBackScale = flashBack.localScale;
        Vector3 flashBackPosition = flashBack.localPosition;
        switch (progressIndex)
        {
            case 0:
                flashBackScale.y = 1f;
                flashBackPosition.y = 0.5f;
                break;
            case 1:
                flashBackScale.y = 1.5f;
                flashBackPosition.y = 0.75f;
                break;
            case 2:
                flashBackScale.y = 2f;
                flashBackPosition.y = 1f;
                break;
        }
        flashBack.localScale = flashBackScale;
        flashBack.localPosition = flashBackPosition;
        if (prepareSpriteSequence.Done)
        {
            outState = EnumState.Working;
        }

    }
    protected void UpdateStateWorking(bool stateChanged, EnumState inState, out EnumState outState)
    {
        outState = inState;

        Vector2 position = (Vector2)transform.position + Vector2.up * 1f;
        if (Utility.GetNearestPlayerPosition(position, out Vector2 nearestPlayerPosition, Person.BodyPart.Foot))
        {
            Vector2 playerDirection = nearestPlayerPosition - new Vector2(transform.position.x, transform.position.y);
            targetDirection = playerDirection;
            float angle = Vector2.SignedAngle(Vector2.left, targetDirection);
            if (angle > 0)
            {
                targetDirection = Vector2.left;
            }
            else if (angle < -60)
            {
                targetDirection = Quaternion.AngleAxis(-60, Vector3.forward) * Vector2.left;
            }
        }


        collider2d.enabled = true;
        LookAtDirection12 target = targetDirection.ToLookAtDirection12();
        LookAtDirection12 current = lookAt.ToLookAtDirection12();

        rotateAction.Update((SeqAction seq) =>
        {
            if (target != current)
            {
                float angle = Vector2.SignedAngle(current.ToVector2(), target.ToVector2());
                if (angle > 0)
                {
                    lookAt = Quaternion.AngleAxis(30, Vector3.forward) * lookAt;
                }
                else
                {
                    lookAt = Quaternion.AngleAxis(-30, Vector3.forward) * lookAt;
                }
            }

        });

        if (target == current)
        {
            fireAction.Update((SeqAction seq) =>
            {
                if (seq.IsFirstAction())
                {
                    seq.PropertyInteger.Add("boxMagazine", boxMagazineSize);
                }
                int boxMagazine = seq.PropertyInteger["boxMagazine"];
                Fire();
                if (--boxMagazine <= 0)
                {
                    fireAction.ReStart();
                }
                else
                {
                    seq.PropertyInteger["boxMagazine"] = boxMagazine;
                }
            });
        }
        sr.sprite = GetLookAtSprite(lookAt.ToLookAtDirection12());

    }

    protected override void UpdateStateDie(bool stateChanged, EnumState inState, out EnumState outState)
{
    base.UpdateStateDie(stateChanged,inState,out outState);
    if(stateChanged){
        if (boomPrefab != null)
        {
            Instantiate(boomPrefab, transform.position, Quaternion.identity);
        }
        Constant.Sounds.EnemyDeath2.PlayOneShot();
        Destroy(gameObject);
    }
}
    private void Fire()
    {
        Vector2 position = transform.position;
        Vector2 offset = Vector3.zero;
        switch (lookAt.ToLookAtDirection12())
        {
            case LookAtDirection12.Left:
                offset += Vector2.left * 1f + Vector2.up * 1f;
                break;
            case LookAtDirection12.LeftLeftUp:
                offset += Vector2.left * 1f + Vector2.up * 1.5f;
                break;
            case LookAtDirection12.UpLeftUp:
                offset += Vector2.left * 0.5f + Vector2.up * 2f;
                break;
        }
        position += offset;

        if (bulletPrefab != null)
        {
            GameObject objBullet = Instantiate(bulletPrefab, position, Quaternion.identity);
            if (objBullet.TryGetComponent<ABullet>(out var aBullet))
            {
                aBullet.SetBulletType(ABullet.BulletType.C);
                aBullet.SetSource(gameObject);
                aBullet.Launch(lookAt);
            }
        }
    }

    private Sprite GetLookAtSprite(LookAtDirection12 lookAtDirection)
    {
        Sprite ret = null;
        foreach (LookAtSprite config in lookAtSpriteConfig)
        {
            if (config.lookAtDirection == lookAtDirection)
            {
                ret = config.sprite;
                break;
            }
        }
        return ret;
    }
}
